import numpy as np

# 我们首先定义了一个`Perceptron`类，该类具有初始化方法`__init__`、拟合方法`fit`、预测方法`predict`以及激活函数`_unit_step_func`。
# 在`fit`方法中，我们使用了随机梯度下降（SGD）算法来更新权重和偏置。在每次迭代中，我们都遍历数据集，并计算每个样本的预测错误，然后使用这些错误来更新权重和偏置。
# 在`predict`方法中，我们计算了线性输出，并应用了激活函数来得到预测结果。
# 最后，我们使用示例数据来训练和预测，并打印出预测结果。

class Perceptron:
    def __init__(self, learning_rate=0.01, n_iters=1000):
        self.lr = learning_rate
        self.n_iters = n_iters
        self.activation_func = self._unit_step_func
        self.weights = None
        self.bias = None

    def fit(self, X, y):
        n_samples, n_features = X.shape

        # 初始化权重和偏置
        self.weights = np.zeros(n_features)
        self.bias = 0

        y_ = np.array([1 if i > 0 else 0 for i in y])

        for _ in range(self.n_iters):
            for idx, x_i in enumerate(X):
                condition = np.dot(x_i, self.weights) + self.bias
                update = self.lr * (y_[idx] - self.activation_func(condition))
                self.weights += update * x_i
                self.bias += update

    def predict(self, X):
        linear_output = np.dot(X, self.weights) + self.bias
        y_pred = self.activation_func(linear_output)
        return y_pred

    def _unit_step_func(self, x):
        return np.where(x >= 0, 1, 0)

    # 示例数据


X = np.array([[1, 2], [2, 3], [3, 3], [2, 1], [3, 2]])
y = np.array([1, 1, 1, 0, 0])

# 创建并训练感知器
p = Perceptron(learning_rate=0.01, n_iters=1000)
p.fit(X, y)

# 预测
predictions = p.predict(X)
print(predictions)